/**
 *                      Copyright 2025 walter
 * <p>
 *      Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 *              http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 *      Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.walter.gitee.service;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.walter.gitee.configuration.GiteeProperties;
import com.walter.gitee.constant.RequestUrlConstant;
import com.walter.gitee.entity.TokenEntity;
import com.walter.gitee.exceptin.GiteeException;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.ContextHolder;

/**
 * gitee oAuth认证接口
 * 接口地址参考：<a href="https://gitee.com/api/v5/oauth_doc#/">https://gitee.com/api/v5/oauth_doc#/</a>
 */
@Component
public class OAuthService {

    @Inject
    private GiteeProperties giteeProperties;

    /**
     * 跳转到认证页面，从gitee跳转回回调地址时，不会携带状态参数
     */
    public void redirect() {
        String url = String.format(RequestUrlConstant.auth_url, giteeProperties.getClientId(), giteeProperties.getRedirectUri());
        ContextHolder.current().redirect(url);
    }

    /**
     * 跳转到认证页面，从gitee跳转回回调地址时，会将 state 字符串作为参数拼接到回调地址中
     *
     * @param state 状态参数
     */
    public void redirectWithState(String state) {
        String url = String.format(RequestUrlConstant.auth_state_url, giteeProperties.getClientId(), giteeProperties.getRedirectUri(), state);
        ContextHolder.current().redirect(url);
    }

    /**
     * 跳转到认证页面
     *
     * @param scope 用户已授权的scope信息
     */
    public void redirectWithScope(String scope) {
        String url = String.format(RequestUrlConstant.scope_auth_url, giteeProperties.getClientId(), giteeProperties.getRedirectUri(), scope);
        ContextHolder.current().redirect(url);
    }

    /**
     * 获取 token，gitee请求回调地址是，会将code作为回调地址的参数拼接到回调地址后面，获取到的token信息需有开发者自行维护，token信息有效期为1天
     */
    public TokenEntity getToken(String code) {
        String url = String.format(RequestUrlConstant.token_url, code, giteeProperties.getClientId(), giteeProperties.getRedirectUri(), giteeProperties.getClientSecret());
        return doTokenReq(url);
    }

    /**
     * 刷新token，当获取的token时效之后，调用该接口获取新的token
     *
     * @param refreshToken 获取token接口响应中的 refresh_token 字段
     */
    public TokenEntity refreshToken(String refreshToken) {
        String url = String.format(RequestUrlConstant.refresh_token_url, refreshToken);
        return doTokenReq(url);
    }

    private TokenEntity doTokenReq(String url) {
        try (cn.hutool.http.HttpResponse httpResponse = HttpUtil.createPost(url).execute()) {
            String body = httpResponse.body();
            if (httpResponse.getStatus() != 200) {
                throw new GiteeException("token获取失败, res=" + body);
            }
            return JSONUtil.toBean(body, TokenEntity.class);
        }
    }
}
